package com.gitee.aurora.engine.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gitee.aurora.core.utils.ResultVO;
import com.gitee.aurora.core.utils.ResultVOUtils;
import com.gitee.aurora.engine.dao.SjzxCheckDao;

import com.gitee.aurora.engine.service.SjzxCheckService;
import com.gitee.aurora.engine.vo.DataCheckVo;
import com.gitee.aurora.engine.vo.DataResultVo;
import com.gitee.aurora.engine.vo.ResultCheckVo;
import com.gitee.aurora.engine.vo.StDataResultVo;
import com.gitee.aurora.engine.vo.SyncBaqDataVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * author: jiangfuxiao
 * Date:2022/9/2 11:34
 */
@Service("sjzxCheckServiceImpl")
public class SjzxCheckServiceImpl implements SjzxCheckService {

    @Resource(name = "sjzxCheckDaoImpl")
    private SjzxCheckDao sjzxCheckDao;

    @Resource
    private RestTemplate restTemplate;

    @Autowired
    private ObjectMapper mapper;

    @Value("${http.sjzxcx}")
    private String sjzxUrlCx;

    @Value("${http.sjzxIdcx}")
    private String sjzxIdcx;

    @Value("${http.sjzxcr}")
    private String sjzxUrlCr;

    @Value("${http.zfjdcx}")
    private String zfjdUrlCx;

    @Value("${http.zfjdcr}")
    private String zfjdUrlCr;

    @Value("${syncMaxTotal}")
    private String syncMaxTotal;



    @Override
    public ResultVO  queryTableData(DataCheckVo checkVo) {
        //创建统一的任务执行时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        checkVo.setInsertDate(format.format(new Date()));
        return countDataCheck(checkVo);
    }


    //办案区->数据中心->省厅数据中心->监督数量统计分析方法
    private ResultVO  countDataCheck(DataCheckVo checkVo){
        //结果集
        ResultCheckVo result = new ResultCheckVo();

        //获取办案区和数据中心以及监督数据
        StDataResultVo stResultVo = requestDataAll(checkVo);

        //返回
        result.setBaqCount(stResultVo.getBaqCount());
        result.setSjzxCount(stResultVo.getSjzxCount());
        result.setStSjzxCount(stResultVo.getStSjzxCount());
        result.setZfjdCount(stResultVo.getZfjdCount());

        //数量分析对比 各组件返回的数据
        if (stResultVo.getBaqCount() > stResultVo.getSjzxCount()){
            //具体逻辑看set方法
            result.setResultBaqDatas(stResultVo);
        }

        if (stResultVo.getSjzxCount() > stResultVo.getStSjzxCount()){
            //具体逻辑看set方法
            result.setResultSjzxDatas(checkVo.getStSjzxIp(), stResultVo);
        }

        if (stResultVo.getStSjzxCount() > stResultVo.getZfjdCount()){
            //具体逻辑看set方法
            result.setResultZfjdDatas(checkVo.getZfjdIp(),stResultVo);
        }

        return ResultVOUtils.success(result);
    }




    public StDataResultVo requestDataAll(DataCheckVo checkVo) {

        List<DataResultVo> sjzxData = new ArrayList<>();
        List<String> sjzxIps = checkVo.getSjzxIp();
        for (String sjzxIp:sjzxIps) {
            DataCheckVo vo = new DataCheckVo();
            BeanUtils.copyProperties(checkVo, vo);
            vo.setSjzxIp(Arrays.asList(sjzxIp));
            queryAllBaqIp(vo);
            DataResultVo baqAndSjzxData = getSjzxData(vo);
            sjzxData.add(baqAndSjzxData);
        }

        List<LinkedCaseInsensitiveMap<Object>> stSjzxData = new ArrayList<>();
        List<Object> ids =new ArrayList<>();
        sjzxData.forEach(v ->{
            checkVo.setIds(v.getSjzxIds());
            ids.addAll(v.getSjzxIds());
            List<LinkedCaseInsensitiveMap<Object>> sjzxDataId = (List<LinkedCaseInsensitiveMap<Object>>)getStSjzxData(checkVo);
            if (!CollectionUtils.isEmpty(sjzxDataId)) {
                stSjzxData.addAll(sjzxDataId);
            }
        });
        checkVo.setIds(ids);
        List<LinkedHashMap<String, Object>> zfjdData = getZFJDData(checkVo);

        StDataResultVo resultVo = new StDataResultVo();

        resultVo.setSjzxData(sjzxData);
        resultVo.setStSjzxData(stSjzxData);
        resultVo.setZfjdData(zfjdData);
        return resultVo;
    }


    private void queryAllBaqIp(DataCheckVo vo){
        List<Map<String, Object>> map = sjzxCheckDao.queryAllBaqIp(vo.getSjzxIp().get(0));
        if (!CollectionUtils.isEmpty(map)){
            List<String> allBaqIp = new ArrayList<>();
            map.forEach(value -> {
                allBaqIp.add(String.valueOf(value.get("baqIp")));
            });
            vo.setBaqIp(allBaqIp);
        }
    }



    private DataResultVo getSjzxData(DataCheckVo checkVo) {
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<DataCheckVo> httpEntity = new HttpEntity<>(checkVo, headers);
        //请求下级数据中心所有办案区数据
        if (!CollectionUtils.isEmpty(checkVo.getSjzxIp())) {
                try {
                   String sjzxUrlCxs = sjzxUrlCx.replace("ip", checkVo.getSjzxIp().get(0));
                    ResponseEntity<ResultVO> responseBaq = restTemplate.exchange(sjzxUrlCxs, HttpMethod.POST, httpEntity, ResultVO.class);
                    DataResultVo dataResultVo = mapper.readValue(mapper.writeValueAsString(responseBaq.getBody().getData()), DataResultVo.class);
                    return dataResultVo ;
                } catch (Exception e) {
                    e.printStackTrace();
            }
        }
        return null;
    }

    private List getStSjzxData(DataCheckVo checkVo) {
        return sjzxCheckDao.queryTableDataByIds(checkVo);
    }

    private List<LinkedHashMap<String, Object>> getZFJDData(DataCheckVo checkVo) {
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<DataCheckVo> httpEntity = new HttpEntity<>(checkVo, headers);
        if (StringUtils.isNotBlank(checkVo.getZfjdIp())){
            String zfjdUrl = zfjdUrlCx.replace("ip",checkVo.getZfjdIp());
            ResponseEntity<ResultVO> responseZfjd = restTemplate.exchange(zfjdUrl, HttpMethod.POST, httpEntity, ResultVO.class);
            return (List<LinkedHashMap<String, Object>>) responseZfjd.getBody().getData();
        }
        return null;
    }


    @Override
    public ResultVO insertData(DataCheckVo vo) {
        return  sjzxCheckDao.insertData(vo);
    }

    @Override
    public ResultVO syncData(ResultCheckVo vo) {

        Map<String, Object> result = filterTolat(vo);

        try {
            syncBaqData(vo);
            syncSjzxData(vo);
            syncStSjzxData(vo);
        }catch (Exception e){
            e.printStackTrace();
            return ResultVOUtils.error("同步数据失败");
        }

        if (!CollectionUtils.isEmpty(result)){
            return ResultVOUtils.success(result);
        }

        return  ResultVOUtils.success("同步数据成功");
    }

    @Override
    public ResultVO getDBTableField(String tableName) {
        return sjzxCheckDao.getDBTableField(tableName);
    }

    private Map<String,Object> filterTolat(ResultCheckVo vo){
        Map<String,Object> reslut  =  new HashMap<>();
        if (!CollectionUtils.isEmpty(vo.getResultBaqData())) {
            vo.getResultBaqData().forEach(v -> {
                v.getGroupBaqData().forEach((k, data) -> {
                    if (!CollectionUtils.isEmpty(data) && data.size() >= Integer.parseInt(syncMaxTotal)) {
                        v.getGroupBaqData().put(k, null);
                        reslut.put(k, "同步数据超过1000条数据量限制，同步失败");
                    }

                });
            });
        }
        return reslut;
    }

    private void syncBaqData(ResultCheckVo vo){
        if (!CollectionUtils.isEmpty(vo.getResultBaqData())){
            // 同步各数据中心缺失的办案区数据
            vo.getResultBaqData().forEach(v -> {
                //根据status筛选需要同步数据的办案区
                if (1 == v.getStatus()){
                    HttpHeaders headers = new HttpHeaders();
                    SyncBaqDataVo syncVo = new SyncBaqDataVo();
                    syncVo.setTableName(vo.getTableName());
                    syncVo.setGroupBaqData(v.getGroupBaqData());
                    HttpEntity<SyncBaqDataVo> httpEntity = new HttpEntity<>(syncVo, headers);
                    String sjzxUrlCrs = sjzxUrlCr.replace("ip",v.getSjzxIp());
                    restTemplate.exchange(sjzxUrlCrs, HttpMethod.POST, httpEntity, ResultVO.class);
                }
            });
        }
    }

    private void syncSjzxData(ResultCheckVo vo){
        if (!CollectionUtils.isEmpty(vo.getResultSjzxData())){
            vo.getResultSjzxData().forEach( v -> {
                if (1 == v.getStatus()){
                    v.getGroupSjzxData().forEach((sjzxIp,data) -> {
                        HttpHeaders headers = new HttpHeaders();
                        DataCheckVo syncVo = new DataCheckVo();
                        syncVo.setTableName(vo.getTableName());
                        syncVo.setIds(data);
                        HttpEntity<DataCheckVo> httpEntity = new HttpEntity<>(syncVo, headers);
                        String sjzxIdcxs = sjzxIdcx.replace("ip",sjzxIp);
                        ResponseEntity<ResultVO> sjzxData = restTemplate.exchange(sjzxIdcxs, HttpMethod.POST, httpEntity, ResultVO.class);
                        try {
                            String listStr = mapper.writeValueAsString(sjzxData.getBody().getData());
                            syncVo.setListStr(listStr);
                            insertData(syncVo);
                        } catch (JsonProcessingException e) {
                            e.printStackTrace();
                        }
                    });
                }
            });
        }

    }

    private void syncStSjzxData(ResultCheckVo vo){
        if (null != vo.getResultZfjdData()){
            DataCheckVo syncVo = new DataCheckVo();
            List<Object> stSjzxIds = vo.getResultZfjdData().getStSjzxIds();
            syncVo.setIds(stSjzxIds);
            syncVo.setTableName(vo.getTableName());
            List list = sjzxCheckDao.queryTableDataByIds(syncVo);
            syncVo.getIds().clear();
            try {
                syncVo.setListStr(mapper.writeValueAsString(list));
                HttpHeaders headers = new HttpHeaders();
                HttpEntity<DataCheckVo> httpEntity = new HttpEntity<>(syncVo, headers);
                String zfjdUrlCrs = zfjdUrlCr.replace("ip",vo.getResultZfjdData().getZfjdIp());
                restTemplate.exchange(zfjdUrlCrs, HttpMethod.POST, httpEntity, ResultVO.class);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

}
